<script setup>
import 'prismjs'
import 'prismjs/themes/prism-tomorrow.css'
import Prism from 'vue-prism-component'

const props = defineProps({
  title: {
    type: String,
    required: true,
  },
  code: {
    type: Object,
    required: true,
  },
  codeLanguage: {
    type: String,
    required: false,
    default: 'js',
  },
  noPadding: {
    type: Boolean,
    required: false,
    default: false,
  },
  showTitle: {
    type: Boolean,
    required: false,
    default: true,
  },
  showCode: {
    type: Boolean,
    required: false,
    default: false,
  },
})

const preferredCodeLanguage = ref('js')
const isCodeShown = ref(props.showCode)
const isTitleShown = ref(props.showTitle)
const noPadding = ref(props.noPadding)
const { copy, copied } = useClipboard({ source: computed(() => props.code['js']) })
</script>

<template>
  <VCard>
    <VCardItem v-if="isTitleShown">
      <VCardTitle>{{ props.title }}</VCardTitle>
      <template #append>
        <IconBtn
          size="small"
          :color="isCodeShown ? 'primary' : 'default'"
          :class="isCodeShown ? '' : 'text-disabled'"
          @click="isCodeShown = !isCodeShown"
        >
          <VIcon
            size="20"
            icon="tabler-code"
          />
        </IconBtn>
      </template>
    </VCardItem>
    <slot v-if="noPadding" />
    <VCardText v-else>
      <slot />
    </VCardText>
    <VExpandTransition>
      <div v-show="isCodeShown">
        <VDivider v-if="isTitleShown" />

        <VCardText
          class="d-flex gap-y-3 flex-column"
          :class="{ 'app-card-code-text': noPadding }"
        >
          <div class="d-flex justify-end">
            <VBtnToggle
              v-show="codeLanguage == 'markup'"
              v-model="preferredCodeLanguage"
              mandatory
              variant="outlined"
              density="compact"
            >
              <VBtn
                v-if="codeLanguage == 'markup' || codeLanguage == 'ts'"  
                size="x-small"
                value="ts"

                :color="preferredCodeLanguage === 'ts' ? 'primary' : 'default'"
              >
                <VIcon
                  size="x-large"
                  icon="custom-typescript"
                  :color="preferredCodeLanguage === 'ts' ? 'primary' : 'secondary'"
                />
              </VBtn>
              <VBtn
                v-if="codeLanguage == 'markup' || codeLanguage == 'js'"
                size="x-small"
                value="js"
                :color="preferredCodeLanguage === 'js' ? 'primary' : 'default'"
              >
                <VIcon
                  size="x-large"
                  icon="custom-javascript"
                  :color="preferredCodeLanguage === 'js' ? 'primary' : 'secondary'"
                />
              </VBtn>
            </VBtnToggle>
          </div>

          <div class="position-relative">
            <Prism
              :key="props.code[preferredCodeLanguage]"
              :language="props.codeLanguage"
              :style="$vuetify.locale.isRtl ? 'text-align: right' : 'text-align: left'"
            >
              {{ props.code[preferredCodeLanguage] }}
            </Prism>
            <IconBtn
              class="position-absolute app-card-code-copy-icon"
              color="white"
              @click="() => { copy() }"
            >
              <VIcon
                :icon="copied ? 'tabler-check' : 'tabler-copy'"
                size="20"
              />
            </IconBtn>
          </div>
        </VCardText>
      </div>
    </VExpandTransition>
  </VCard>
</template>

<style lang="scss">
@use "@styles/variables/_vuetify.scss";

:not(pre) > code[class*="language-"],
pre[class*="language-"] {
  border-radius: vuetify.$card-border-radius;
}

.app-card-code-copy-icon {
  inset-block-start: 1.2em;
  inset-inline-end: 0.8em;
}

.app-card-code-text {
  padding: 0 !important;
}
</style>
